package dkbta.ontology.elements.abstractions.gradient;

import java.util.List;

import dkbta.ontology.elements.Element;
import dkbta.ontology.elements.abstractions.PairedMappingFunction;
import dkbta.ontology.elements.abstractions.interpolation.PersistenceFunction;
import dkbta.util.time.TimeUnit;
import dkbta.util.time.TimeUtils;

/**
 * A paired mapping function for gradients
 * 
 * @author Uri Kanonov
 */
public class GradientMappingFunction extends PairedMappingFunction<Gradient>{
	private static final String DECREASING = "Decreasing";

	private static final String SAME = "Same";

	private static final String INCREASING = "Increasing";

	/** The values that are required by a Gradient abstraction */
	public static final String[] NECESSARY_VALUES = {DECREASING, SAME, INCREASING};

	/**
	 * The variation threshold that decides whether a trend between two primitives is
	 * decreasing, same or increasing
	 */
	private final double _significantVariation;

	/**
	 * Initializes a gradient mapping function
	 * 
	 * @param significantVariation The variation threshold that decides whether a trend
	 *        between two primitives is decreasing, same or increasing
	 * @param timeUnit The time unit based per which are the angle and
	 *        significantVariation
	 */
	public GradientMappingFunction(double significantVariation, TimeUnit timeUnit){
		// Adjusting the significantVariation to be per millisecond
		_significantVariation = TimeUtils.convertFromTimeUnitToMillis(
			significantVariation, timeUnit);
	}

	@Override
	public String toString(){
		StringBuilder sb = new StringBuilder();
		sb.append("Significant Variation: ").append(_significantVariation).append("\r\n");
		return sb.toString();
	}

	@Override
	protected String calculateValue(double variationPerMillisecond){
		// Determining the value of the gradient according to the significantVariation
		if (variationPerMillisecond > _significantVariation){
			return INCREASING;
		}else if (variationPerMillisecond < -_significantVariation){
			return DECREASING;
		}else{
			return SAME;
		}
	}

	@Override
	protected void mapElements(List<Gradient> abstractions, String abstractionName,
		Element before, Element after, PersistenceFunction interpolation){
		String value = mapPair(before, after, interpolation);
		if (value != null){
			abstractions.add(new Gradient(abstractionName, before.getTimeInterval()
					.getStartTime(), after.getTimeInterval().getEndTime(), value));
		}
	}
}
